package com.ll.domain.classbase.biz.impl;

import com.ll.base.enums.ResultCodeEnum;
import com.ll.base.dto.ApiResultDTO;
import com.ll.base.dto.PageReqDTO;
import com.ll.base.dto.PageResultDTO;
import com.ll.base.util.ExcelUtil;
import com.ll.base.util.ListUtil;
import com.ll.base.util.ScalarUtil;
import com.ll.domain.classbase.base.ClassBaseService;
import com.ll.domain.classbase.convert.CourseConvert;
import com.ll.domain.classbase.dto.ClassBaseDTO;
import com.ll.domain.classbase.dto.CreateClassGroupDTO;
import com.ll.domain.classbase.event.producer.AddCourserEvent;
import com.ll.domain.dingtalk.base.DingTalkUserBaseService;
import com.ll.domain.dingtalk.dto.DingGroupDTO;
import com.ll.domain.dingtalk.utils.AccessTokenUtil;
import com.ll.domain.classbase.biz.ClassBaseDomainService;
import com.ll.domain.classbase.convert.ClassBaseConvert;
import com.ll.domain.pk.convert.PkConvert;
import com.ll.domain.pk.event.producer.AddPkEvent;
import com.ll.domain.user.base.UserBaseService;
import com.ll.domain.user.convert.StudentConvert;
import com.ll.dal.po.ClassBasePO;
import com.ll.domain.user.dto.StudentDTO;
import com.ll.domain.user.dto.UserDTO;
import com.ll.app.api.req.AddClassBaseReqDTO;
import com.ll.domain.classbase.enums.ClassBaseStatusEnum;
import com.ll.domain.user.enums.RoleEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class ClassBaseDomainServiceImpl implements ClassBaseDomainService {
    private final ClassBaseService classBaseService;
    private final DingTalkUserBaseService dingTalkUserBaseService;
    private final UserBaseService userBaseService;
    private static List DEFAULT_STUDENT_IDS = Collections.EMPTY_LIST;
    private static Map<Integer, String> DEFAULT_STUDENT_MAP = new HashMap<>();
    private final ApplicationEventPublisher applicationEventPublisher;

    static {
        String[] ids = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
        DEFAULT_STUDENT_IDS = Arrays.asList(ids);
        DEFAULT_STUDENT_MAP.put(1, "纪方,法亚,周智,奚熙,晴伊,庄炜,骁榕,柒夏,欣慰,玑衡");
        DEFAULT_STUDENT_MAP.put(2, "狼顾,梁灿,约瑟,普松,哲欣,张润星,陈文慧,乔稳,湖鹰,海漠");
        DEFAULT_STUDENT_MAP.put(3, "临崖,琉醇,君绝,守壹,鱼悦,菲林,芊仞,止珩,齐琴婷,盈之");
        DEFAULT_STUDENT_MAP.put(4, "苩虹,寻石,千玉,煜燃,凌泉,大瑃,思动,黛桉,文进,林依");
    }

    private static String managerDingUserIds = "04453518411031247,1844652736858142," +
            "14355409661117425,144101591524298585,016015631040325," +
            "1333622629-2011177204,1211254947431294671,1054095253647292,432262641317";

    @Override
    public PageResultDTO<ClassBaseDTO> page(PageReqDTO req) {
        PageResultDTO<ClassBasePO> page = classBaseService.page(req);
        PageResultDTO<ClassBaseDTO> result = PageResultDTO.PageBuildDTO(page, ClassBaseConvert::PO2DTO);

        //初始化的班级
        result.getDatas().stream()
                .filter(r -> DEFAULT_STUDENT_MAP.containsKey(r.getIndexNum()))
                .forEach(r -> {
                    r.setStudentIds(DEFAULT_STUDENT_IDS);
                });
        return result;
    }

    @Override
    public Map<String, String> listStudentName(Long id) {
        ClassBasePO classBasePO = classBaseService.getById(id);
        ClassBaseDTO classBaseDTO = ClassBaseConvert.PO2DTO(classBasePO);
        if (classBaseDTO != null &&
                ScalarUtil.isNotEmpty(classBaseDTO.getStudentIds())
                && !DEFAULT_STUDENT_MAP.containsKey(classBasePO.getIndexNum())) {
            String token = AccessTokenUtil.getToken();
            List<UserDTO> userDTOS = ListUtil.toList(classBaseDTO.getStudentIds(), uid -> dingTalkUserBaseService.getByUserId(token, uid));
            return ListUtil.toMap(userDTOS, UserDTO::getDingTalkUserId, UserDTO::getUserName);
        }

        if (DEFAULT_STUDENT_MAP.containsKey(classBasePO.getIndexNum())) {
            String names = DEFAULT_STUDENT_MAP.get(classBasePO.getIndexNum());
            String[] split = names.split(ScalarUtil.DEFAULT_STRING_SPLIT);
            return ListUtil.toMap(Arrays.asList(split), r -> UUID.randomUUID().toString(), v -> v);
        }

        return new HashMap<>();
    }

    @Override
    public ApiResultDTO exportStudentByIds(CreateClassGroupDTO createClassGroupDTO, HttpServletResponse response) {
        UserDTO userDTO = userBaseService.getByDingUserId(createClassGroupDTO.getDingTalkUserId());
        if(userDTO == null || userDTO.getRoleCode() < RoleEnum.教练.getId()){
            ApiResultDTO.failure(ResultCodeEnum.POWER_ERROR);
        }
        List<ClassBasePO> classBasePOS = classBaseService.listByIndexNums(createClassGroupDTO.getIndexIds());
        List<StudentDTO> studentDTOS = new ArrayList<>();
        StringBuilder groupNameBuilder = new StringBuilder();
        for(ClassBasePO classBasePO: classBasePOS) {
            ClassBaseDTO classBaseDTO = ClassBaseConvert.PO2DTO(classBasePO);
            groupNameBuilder.append(classBaseDTO.getIndexNum()).append(ScalarUtil.DEFAULT_DH);
            List<StudentDTO> studentDTO2 = new ArrayList<>();
            if (DEFAULT_STUDENT_MAP.containsKey(classBaseDTO.getIndexNum())) {
                String names = DEFAULT_STUDENT_MAP.get(classBaseDTO.getIndexNum());
                String[] split = names.split(ScalarUtil.DEFAULT_STRING_SPLIT);
                studentDTO2 = ListUtil.toList(Arrays.asList(split), r -> StudentConvert.userName2StudentDTO(r, classBaseDTO));
            } else if (ScalarUtil.isNotEmpty(classBaseDTO.getStudentIds()) && !DEFAULT_STUDENT_MAP.containsKey(classBaseDTO.getIndexNum())) {
                List<UserDTO> userDTOS = userBaseService.getByDingUids(classBaseDTO.getStudentIds());
                studentDTO2 = ListUtil.toList(userDTOS, r -> StudentConvert.userDTO2StudentDTO(r, classBaseDTO));
            }
            studentDTOS.addAll(studentDTO2);
        }
        String fileName = groupNameBuilder.substring(0, groupNameBuilder.length() - 1) + "班级人员列表";
        ExcelUtil<StudentDTO> excelUtil= new ExcelUtil<>(StudentDTO.class);
        excelUtil.exportExcel(studentDTOS, fileName, response);
        return ApiResultDTO.success();
    }


    public List<StudentDTO> listStudentByIds(List<Long> ids){
        List<ClassBasePO> classBasePOS = classBaseService.listByIds(ids);
        List<StudentDTO> studentDTOS = new ArrayList<>();
        for(ClassBasePO classBasePO: classBasePOS){
            ClassBaseDTO classBaseDTO = ClassBaseConvert.PO2DTO(classBasePO);
            List<StudentDTO> studentDTO2 = new ArrayList<>();
            if (DEFAULT_STUDENT_MAP.containsKey(classBaseDTO.getIndexNum())) {
                String names = DEFAULT_STUDENT_MAP.get(classBaseDTO.getIndexNum());
                String[] split = names.split(ScalarUtil.DEFAULT_STRING_SPLIT);
                studentDTO2 = ListUtil.toList(Arrays.asList(split), r ->StudentConvert.userName2StudentDTO(r, classBaseDTO));
            }else  if (ScalarUtil.isNotEmpty(classBaseDTO.getStudentIds()) && !DEFAULT_STUDENT_MAP.containsKey(classBaseDTO.getIndexNum())) {
                List<UserDTO> userDTOS = userBaseService.getByDingUids(classBaseDTO.getStudentIds());
                studentDTO2  = ListUtil.toList(userDTOS, r -> StudentConvert.userDTO2StudentDTO(r, classBaseDTO));
            }
            studentDTOS.addAll(studentDTO2);
        }
        return studentDTOS;
    }

    @Override
    public ApiResultDTO updateExtData(Long id, String data) {
        String[] split = data.split(ScalarUtil.DEFAULT_STRING_SPLIT);
        if (split.length > 10) {
            return ApiResultDTO.failure(ResultCodeEnum.CLASS_APPLY_MAX.getCode(),
                    "当前班级人数已满不可报名");
        }
        classBaseService.updateExtData(id, data);
        return ApiResultDTO.success();
    }

    @Override
    public void updateStatus(Long id, ClassBaseStatusEnum status) {
        classBaseService.updateStatus(id, status);
    }

    @Override
    public Long add(AddClassBaseReqDTO addClassBaseReqDTO) {
        ClassBasePO classBasePO = ClassBaseConvert.addClassBaseReqDTO2PO(addClassBaseReqDTO);

        classBaseService.save(classBasePO);

        return classBasePO.getId();
    }

    @Override
    public ApiResultDTO createClassGroup(CreateClassGroupDTO createClassGroupDTO) {
        UserDTO userDTO = userBaseService.getByDingUserId(createClassGroupDTO.getDingTalkUserId());
        if(userDTO == null || userDTO.getRoleCode() < RoleEnum.教练.getId()){
            ApiResultDTO.failure(ResultCodeEnum.POWER_ERROR);
        }

        List<Long> classIds = createClassGroupDTO.getClassIds();
        List<ClassBasePO> classBasePOS = classBaseService.listByIds(classIds);
        StringBuilder groupUserIdsBuilder = new StringBuilder();
        StringBuilder groupNameBuilder = new StringBuilder();
        for (ClassBasePO r : classBasePOS) {
            groupUserIdsBuilder.append(r.getExtData());
            groupNameBuilder.append(r.getIndexNum()).append(ScalarUtil.DEFAULT_DH);
        }
        String groupUids = groupUserIdsBuilder.toString() + managerDingUserIds;
        String groupName = groupNameBuilder.substring(0, groupNameBuilder.length() - 1) + "班级群";

        DingGroupDTO dto = DingGroupDTO.builder()
                .groupName(groupName)
                .groupUserIds(groupUids)
                .masterDingUid(createClassGroupDTO.getDingTalkUserId())
                .token(AccessTokenUtil.getToken()).build();
        dingTalkUserBaseService.createGroup(dto);
        return ApiResultDTO.success();
    }
}
